package com.shareroad.dubboweb.frame.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shareroad.dubboweb.frame.base.Constants;
import com.shareroad.dubboweb.frame.handler.ApiHandler;
import com.shareroad.dubboweb.frame.model.entity.ErrorCode;
import com.shareroad.dubboweb.frame.model.entity.ReturnObject;

@RestController
public class ApiController {
	
	private static final Logger logger = LoggerFactory.getLogger(ApiController.class);
	
	@Autowired
	private ApiHandler apiHandler;
    
	/**
	 * api 主方法
	 * @param request
	 * @param response
	 * @param interfaceName
	 * @param version
	 * @param method
	 * @param params
	 * @return
	 */
    @ResponseBody
    @RequestMapping(value="/api") 
	public ReturnObject api(
			HttpServletRequest request, 
			HttpServletResponse response,
			@RequestParam(value="_i",required=false) String interfaceName,
			@RequestParam(value="_v",required=false) String version,
			@RequestParam(value="_m",required=false) String method,
			@RequestParam(value="_p",required=false,defaultValue="{}") String params){
    	
    	setResponseHeader(response);
    	StringBuilder logStr = new StringBuilder();
    	logStr.append("_i="+interfaceName);
    	logStr.append(",_v="+version);
    	logStr.append(",_m="+method);
    	logStr.append(",_p="+params);
    	logger.info(logStr.toString());
    	long start = System.currentTimeMillis();
    	ReturnObject ro = new ReturnObject();
    	try{
	    	if(StringUtils.isEmpty(interfaceName)){
	    		ro.setStatus(Constants.HTTP_500);
	    		ro.setErrorCode(ErrorCode.api_param_interface_miss.getCode());
	    		ro.setErrorDesc(ErrorCode.api_param_interface_miss.getDesc());
	    		ro.setUseTime(System.currentTimeMillis() - start);
	    		logStr.append(",error:"+JSON.toJSONString(ro));
	    		logger.error(logStr.toString());
	    		
	    		return ro;
	    	}
	    	
	    	if(StringUtils.isEmpty(method)){
	    		ro.setStatus(Constants.HTTP_500);
	    		ro.setErrorCode(ErrorCode.api_param_method_miss.getCode());
	    		ro.setErrorDesc(ErrorCode.api_param_method_miss.getDesc());
	    		ro.setUseTime(System.currentTimeMillis() - start);
	    		logStr.append(",error:"+JSON.toJSONString(ro));
	    		logger.error(logStr.toString());
	    		
	    		return ro;
	    	}
	    	
	    	JSONObject paramObject = null;
	    	try{
	    		paramObject = JSONObject.parseObject(params);
	    	}catch(Exception e){
	    		ro.setStatus(Constants.HTTP_500);
	    		ro.setErrorCode(ErrorCode.api_param_params_illegal.getCode());
	    		ro.setErrorDesc(ErrorCode.api_param_params_illegal.getDesc());
	    		ro.setUseTime(System.currentTimeMillis() - start);
	    		logStr.append(",error:"+JSON.toJSONString(ro));
	    		logger.error(logStr.toString());
	    		
	    		return ro;
	    	}
	    	try{
	    		ro = apiHandler.invokeDubboService(interfaceName,version, method, paramObject);
	    		ro.setUseTime(System.currentTimeMillis() - start);
	    		logStr.append(",call dubbo result : "+JSON.toJSONString(ro));
	    		logger.info(logStr.toString());
	    		
	    		return ro;
	    	}catch(Exception e){
	    		e.printStackTrace();
	    		ro.setStatus(Constants.HTTP_500);
	    		ro.setErrorCode(ErrorCode.api_dubbo_service_error.getCode());
	    		ro.setErrorDesc(ErrorCode.api_dubbo_service_error.getDesc());
	    		ro.setUseTime(System.currentTimeMillis() - start);
	    		logStr.append(",error:"+JSON.toJSONString(ro));
	    		logger.error(logStr.toString());
	    		
	    		return ro;
	    	}
    	}catch(Exception e){
    		ro.setStatus(Constants.HTTP_500);
    		ro.setErrorCode(ErrorCode.api_system_error.getCode());
    		ro.setErrorDesc(ErrorCode.api_system_error.getDesc());
    		ro.setUseTime(System.currentTimeMillis() - start);
    		logStr.append(",error:"+JSON.toJSONString(ro));
    		logger.error(logStr.toString());
    		
    		return ro;
    	}
	}
    

    @ResponseBody
    @RequestMapping("/error")
    public ReturnObject error(HttpServletRequest request, 
			HttpServletResponse response){
    	setResponseHeader(response);
    	ReturnObject ro = new ReturnObject();
    	ro.setStatus(Constants.HTTP_404);
		ro.setErrorCode(ErrorCode.api_url_error.getCode());
		ro.setErrorDesc(ErrorCode.api_url_error.getDesc());
		return ro;
    }
    
    @ResponseBody
    @RequestMapping("/error405")
    public ReturnObject error405(HttpServletRequest request, 
			HttpServletResponse response){
    	setResponseHeader(response);
    	ReturnObject ro = new ReturnObject();
    	ro.setStatus(Constants.HTTP_405);
		ro.setErrorCode(ErrorCode.api_error_405.getCode());
		ro.setErrorDesc(ErrorCode.api_error_405.getDesc());
		return ro;
    }
    
    @ResponseBody
    @RequestMapping("/error406")
    public ReturnObject error406(HttpServletRequest request, 
			HttpServletResponse response){
    	setResponseHeader(response);
    	ReturnObject ro = new ReturnObject();
    	ro.setStatus(Constants.HTTP_406);
		ro.setErrorCode(ErrorCode.api_error_406.getCode());
		ro.setErrorDesc(ErrorCode.api_error_406.getDesc());
		return ro;
    }
    
    /**设置 response */
    private void setResponseHeader(HttpServletResponse response){
    	//设置跨域
    	response.setHeader("Access-Control-Allow-Origin", "*");
    }

    
}
